package com.cartagena.financo.controller;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;

import com.cartagena.financo.model.Category;
import com.cartagena.financo.model.Transaction;
import com.cartagena.financo.model.TransactionType;
import com.cartagena.financo.repository.CategoryRepository;
import com.cartagena.financo.repository.TransactionRepository;
import com.cartagena.financo.util.CategorySum;
import com.cartagena.financo.util.ChartEntry;
import com.cartagena.financo.util.ChartMonthEntry;
import com.cartagena.financo.util.DateUtil;
import com.cartagena.financo.util.TransactionUtil;
import com.cartagena.vraptor.extjs.ExtJSJson;

@Resource
public class ChartController {

    private static final String DEFAULT_CATEGORY = "Salário";
    
    private final Result result;
    private final TransactionRepository transactionRepository;
    private final CategoryRepository categoryRepository;

    public ChartController(Result result, TransactionRepository transactionRepository, CategoryRepository categoryRepository) {
        this.result = result;
        this.transactionRepository = transactionRepository;
        this.categoryRepository = categoryRepository;
    }

    @Path("/chart/category")
    public void category(Date begin, Date end) {
        if (begin == null) {
            begin = DateUtil.getDefaultMonthBegin();
        }

        if (end == null) {
            end = DateUtil.getDefaultMonthEnd();
        }

        List<Transaction> transactions = transactionRepository.listByPeriod(begin, end);        
        List<CategorySum> sums = TransactionUtil.sumGrouped(transactions, TransactionType.DEBIT);
        List<ChartEntry> result = new ArrayList<ChartEntry>();

        
        for(CategorySum sum : sums) {
            result.add(new ChartEntry(sum.getCategory().getName(), sum.getTotal()));
        }

        this.result.use(ExtJSJson.class).from(result).success().serialize();

    }

    @Path("/chart/balance")
    public void monthBalance(Date begin, Date end) {
        if (begin == null) {
            begin = DateUtil.getDefaultMonthBegin();            
        }
        
        if (end == null) {
            end = DateUtil.getDefaultMonthEnd();
        }
        
        Calendar beginCalendar = Calendar.getInstance();
        beginCalendar.setTime(begin);
        
        List<ChartMonthEntry> result = new ArrayList<ChartMonthEntry>();
        SimpleDateFormat sdf = new SimpleDateFormat("MM/yyyy");
        
        for(int i = 0; i < DateUtil.monthsBetween(end, begin); i++) {
            beginCalendar.add(Calendar.MONTH, i == 0 ? 0 : 1);
            
            
            List<Transaction> transactions = transactionRepository.listByPeriod(DateUtil.getMonthFirstDay(beginCalendar), DateUtil.getMonthLastDay(beginCalendar));
            
            BigDecimal debit = TransactionUtil.sum(transactions, TransactionType.DEBIT);
            BigDecimal credit = TransactionUtil.sum(transactions, TransactionType.CREDIT);
            BigDecimal founds = TransactionUtil.sum(transactions, TransactionType.FOUNDS);
            
            result.add(new ChartMonthEntry(sdf.format(beginCalendar.getTime()), debit, credit, founds));
        }
        
        this.result.use(ExtJSJson.class).from(result).success().serialize();        
    }
    
    @Path("/chart/categoryevolution")
    public void categoryEvolution(Date begin, Date end, Category category) {
        if (begin == null) {
            begin = DateUtil.getDefaultMonthBegin();            
        }
        
        if (end == null) {
            end = DateUtil.getDefaultMonthEnd();
        }
        
        if(category == null) {
            category = categoryRepository.loadByName(DEFAULT_CATEGORY);
        }        
 
        Calendar beginCalendar = Calendar.getInstance();
        beginCalendar.setTime(begin);
        
        List<ChartMonthEntry> result = new ArrayList<ChartMonthEntry>();        
        SimpleDateFormat sdf = new SimpleDateFormat("MM/yyyy");
                
        for(int i = 0; i < DateUtil.monthsBetween(end, begin); i++) {
            beginCalendar.add(Calendar.MONTH, i == 0 ? 0 : 1);
                        
            List<Transaction> transactions = transactionRepository.listByCategoryAndPeriod(category, DateUtil.getMonthFirstDay(beginCalendar), DateUtil.getMonthLastDay(beginCalendar));
            BigDecimal sum = TransactionUtil.sum(transactions);
            
            result.add(new ChartMonthEntry(sdf.format(beginCalendar.getTime()), sum, null, null));
        }
                
        this.result.use(ExtJSJson.class).from(result).success().serialize();        
    }


}
